package com.mickey.controller;

import com.mickey.access.AccessLimit;
import com.mickey.domain.MiaoshaOrder;
import com.mickey.domain.MiaoshaUser;
import com.mickey.domain.OrderInfo;
import com.mickey.rabbitmq.MQSender;
import com.mickey.rabbitmq.MiaoshaMessage;
import com.mickey.redis.AccessKey;
import com.mickey.redis.GoodsKey;
import com.mickey.redis.RedisService;
import com.mickey.result.CodeMsg;
import com.mickey.result.Result;
import com.mickey.service.GoodsService;
import com.mickey.service.MiaoshaService;
import com.mickey.service.MiaoshaUserService;
import com.mickey.service.OrderService;
import com.mickey.vo.GoodsVO;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("miaosha")
public class MiaoshaController implements InitializingBean{

    @Autowired
    private MiaoshaService miaoshaService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MQSender mqSender;

    @Autowired
    private GoodsService goodsService;

    private Map<Long,Boolean> localOverMap = new HashMap<>();

    /**
     * 系统初始化(库存加载到缓存)
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        List<GoodsVO> goodsVOList = goodsService.listGoodsVO();
        if (goodsVOList == null){
            return;
        }
        for (GoodsVO good:goodsVOList) {
            redisService.set(GoodsKey.getMiaoshaGoodsStock,""+good.getId(),good.getStockCount());
            localOverMap.put(good.getId(),false);
        }
    }

    @RequestMapping(value = "/{path}/do_miaosha",method = RequestMethod.POST)
    @ResponseBody
    public Result<Integer> miaosha(Model mode, MiaoshaUser user,
                              @RequestParam("goodsId")long goodsId,
                                   @PathVariable("path") String path){
        mode.addAttribute("user",user);
        if(user == null){
            return Result.err(CodeMsg.SESSION_ERROR);
        }

        //验证path
        boolean check = miaoshaService.checkPath(user, goodsId, path);
        if(!check){
            return Result.err(CodeMsg.REQUEST_ILLEGAL);
        }
        //内存标记，减少redis访问
        Boolean over =  localOverMap.get(goodsId);
        if (over){
            return Result.err(CodeMsg.MIAOSHA_STOCK_NOT);
        }
        //预减库存
        long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock,""+goodsId);
        if (stock < 0){
            localOverMap.put(goodsId,true);
            return Result.err(CodeMsg.MIAOSHA_STOCK_NOT);
        }
        //判断是否已经秒杀过
        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(),goodsId);
        if(order !=null){
            return Result.err(CodeMsg.MIAOSHA_REPEATE);
        }
        //入队
        MiaoshaMessage miaoshaMessage = new MiaoshaMessage();
        miaoshaMessage.setMiaoshaUser(user);
        miaoshaMessage.setGoodsId(goodsId);
        mqSender.sendMiaoshaMessage(miaoshaMessage);

        return Result.sucess(0);//排队中
    }


    /**
     * orderId:成功
     * -1:秒杀失败
     * 0:排队中
     * @param mode
     * @param user
     * @param goodsId
     * @return
     */
    @RequestMapping(value = "/result",method = RequestMethod.GET)
    @ResponseBody
    public Result<Long> result(Model mode, MiaoshaUser user,
                                   @RequestParam("goodsId")long goodsId) {
        mode.addAttribute("user",user);
        if(user == null){
            return Result.err(CodeMsg.SESSION_ERROR);
        }
        long result = miaoshaService.getMiaoshaResult(user.getId(),goodsId);
        return Result.sucess(result);
    }


    @AccessLimit(seconds=5, maxCount=5, needLogin=true)
    @RequestMapping(value="/path", method=RequestMethod.GET)
    @ResponseBody
    public Result<String> getMiaoshaPath(HttpServletRequest request, MiaoshaUser user,
                                         @RequestParam("goodsId")long goodsId,
                                         @RequestParam(value="verifyCode", defaultValue="0")int verifyCode
    ) {
        if(user == null) {
            return Result.err(CodeMsg.SESSION_ERROR);
        }
        boolean check = miaoshaService.checkVerifyCode(user, goodsId, verifyCode);
        if(!check) {
            return Result.err(CodeMsg.REQUEST_ILLEGAL);
        }
        String path  =miaoshaService.createMiaoshaPath(user, goodsId);
        return Result.sucess(path);
    }

    @RequestMapping(value="/verifyCode", method=RequestMethod.GET)
    @ResponseBody
    public Result<String> getMiaoshaVerifyCod(HttpServletResponse response, MiaoshaUser user,
                                              @RequestParam("goodsId")long goodsId) {
        if(user == null) {
            return Result.err(CodeMsg.SESSION_ERROR);
        }
        try {
            BufferedImage image  = miaoshaService.createVerifyCode(user, goodsId);
            OutputStream out = response.getOutputStream();
            ImageIO.write(image, "JPEG", out);
            out.flush();
            out.close();
            return null;
        }catch(Exception e) {
            e.printStackTrace();
            return Result.err(CodeMsg.MIAOSHA_FAIL);
        }
    }


}
